#pragma once
#include <iostream>
#include <string>
#include <cstring>
#include <functional>
#include "Protocol.hpp"
#include "TcpServer.hpp"
using namespace std;

// 计算器业务处理
bool calProcess(const Request &req, Response &resp)
{
    // 此时请求req已经反序列化完成，根据业务处理创建应答resp
    resp._exitcode = OK;
    resp._result = OK;

    switch (req._op)
    {
    case '+':
        resp._result = req._x + req._y;
        break;
    case '-':
        resp._result = req._x - req._y;
        break;
    case '*':
        resp._result = req._x * req._y;
        break;
    case '/':
    {
        if (req._y == 0)
            resp._exitcode = DIV_ZERO;
        else
            resp._result = req._x / req._y;
    }
    break;
    case '%':
    {
        if (req._y == 0)
            resp._exitcode = MOD_ZERO;
        else
            resp._result = req._x % req._y;
    }
    default:
        resp._exitcode = OP_ERR;
        break;
    }
    return false;
}

void Calculate(YZCTcpServer::Connection *conn)
{
    std::string onePackage;
    while (ParseOnePackage(conn->_inbuffer, &onePackage))
    {
        std::string reqStr;
        if (!deLength(onePackage, &reqStr))
            return;
        std::cout << "去掉报头的正文：\n"
                  << reqStr << std::endl;

        // 2. 对请求Request，反序列化
        // 2.1 得到一个结构化的请求对象
        Request req;
        if (!req.deserialize(reqStr))
            return;

        // 3.根据请求构建响应报文
        Response resp;
        calProcess(req, resp);

        // 4.序列化响应报文
        std::string respStr;
        resp.serialize(&respStr);
        // 5. 然后我们在发送响应
        // 5.1 构建成为一个完整的报文
        conn->_outbuffer += enLength(respStr);

        std::cout << "--------------result:\n"
                  << conn->_outbuffer << std::endl;
    }
    // 尝试发送数据
    if (conn->_sender)
        conn->_sender(conn);

    // 如果没有发送完毕，让epoll关心这个fd是否能继续发送数据
    // 通过回指指针，找到TCP中的EanbleWrite并且调用这个方法
    //     if (!conn->_outbuffer.empty())
    //         conn->_tsvrp->EnableReadWrite(conn, true, true);
    //     else
    //         conn->_tsvrp->EnableReadWrite(conn, false, true);
}
